package hospital.action;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import hospital.model.DocScheduleModel;
import hospital.model.PatientInfoModel;
import hospital.model.RecordDetailModel;
import hospital.util.HospitalUtil;
import hospital.service.PatientService;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

public class PatientOperation extends ActionSupport implements Preparable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private HospitalUtil hospitalUtil;
	private PatientInfoModel patientInfo;
	private String firstname;
	private String lastname;
	private String email;
	private String sin;
	private String ohip;
	private String gender;
	private String phoneNum;
	private String cellphone;
	private String address;
	private String postalCode;
	private String defaultDoctor;
	private String year;
	private String month;
	private String day;
	private String currentHealth;
	private String date;
	private PatientService patientService;

	private List<DocScheduleModel> patientAppointments;

	private boolean passwordConfirm;
	private String password;
	private List<RecordDetailModel> recordDetailList;

	private String origPassword;
	private String newPassword;
	private String confirmedNewPassword;

	private String message;
	private boolean flag;

	private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
			+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
	private static final String POSTALCODE_PATTERN = "^[A-Z]{1}\\d{1}[A-Z]{1}\\d{1}[A-Z]{1}\\d{1}$";
	private static final String PHONE_PATTERN = "\\d{10}";

	@Override
	public void prepare() throws Exception {
		clearActionErrors();
		clearFieldErrors();
	}

	public String updatePage() {
		return SUCCESS;
	}

	public String lookupPatientInfo() {
		patientInfo = patientService.lookupPatientInfo();
		return SUCCESS;
	}

	public String updatePatientInfo() {
		message = "";
		flag = true;
		if (gender.equals("-1") || firstname.trim().equals("") || lastname.trim().equals("") || date.trim().equals("")
				|| phoneNum.trim().equals("") || cellphone.trim().equals("") || address.trim().equals("")
				|| postalCode.trim().equals("") || currentHealth.trim().equals("") || email.trim().equals("")) {
			flag = false;
			message += "All fields are required.<br />";
		}
		Pattern pattern = Pattern.compile(EMAIL_PATTERN);
		Matcher matcher = pattern.matcher(email.trim());
		Pattern patternPostal = Pattern.compile(POSTALCODE_PATTERN);
		Matcher matcherPostal = patternPostal.matcher(postalCode.trim());
		Pattern patternPhone = Pattern.compile(PHONE_PATTERN);
		Matcher matcherPhone = patternPhone.matcher(phoneNum.trim());
		Matcher matcherCellP = patternPhone.matcher(cellphone.trim());
		if (!matcher.matches()) {
			flag = false;
			message += "The email is not valid.<br />";
		}
		if (!matcherPostal.matches()) {
			flag = false;
			message += "The postal code is not valid.<br />";
		}
		if (!matcherPhone.matches()) {
			flag = false;
			message += "The home phone number is not valid.<br />";
		}
		if (!matcherCellP.matches()) {
			flag = false;
			message += "The cellphone number is not valid.<br />";
		}
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
		Date parsedDate = null;
		try {
			parsedDate = sdf.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			flag = false;
			message += "Date of birth is not valid.<br />";
		}
		if (parsedDate != null) {
			Calendar c = Calendar.getInstance();
			c.setTime(parsedDate);
			if (c.getTimeInMillis() > Calendar.getInstance().getTimeInMillis()) {
				flag = false;
				message += "The date of birth should not come after the current time.<br />";
			}
		}
		if (flag == false) {
			return SUCCESS;
		}
		boolean res = patientService.updateUsername(email.trim());
		if (!res) {
			flag = false;
			message = "Fail to update information.";
			return SUCCESS;
		}
		patientInfo.setFirstname(firstname.trim());
		patientInfo.setLastname(lastname.trim());

		if (parsedDate != null) {
			patientInfo.setDateOfBirth(parsedDate);
		}
		if (gender.equals("male")) {
			patientInfo.setGender('m');
		} else {
			patientInfo.setGender('f');
		}
		patientInfo.setPhonenum(phoneNum.trim());
		patientInfo.setCellphone(cellphone.trim());
		patientInfo.setAddress(address.trim());
		patientInfo.setPostalCode(postalCode.trim());
		patientInfo.setCurrentHealth(currentHealth.trim());

		boolean result = patientService.updatePatient(patientInfo);
		if (result) {
			flag = true;
			message = "Update successfully.";
			return SUCCESS;
		} else {
			flag = false;
			message = "Fail to update information.";
			return SUCCESS;
		}
	}

	public String appointmentPage() {
		return SUCCESS;
	}

	public String lookupAppointment() {
		patientAppointments = patientService.lookupAppointment();
		Iterator<DocScheduleModel> it = patientAppointments.iterator();
		DocScheduleModel tmp = new DocScheduleModel();
		long patientId, doctorId, staffId;
		while (it.hasNext()) {
			tmp = it.next();
			patientId = tmp.getPatientId();
			tmp.setPatientId(hospitalUtil.idWrapper(patientId, (byte) 0));
			doctorId = tmp.getDoctorId();
			tmp.setDoctorId(hospitalUtil.idWrapper(doctorId, (byte) 1));
			staffId = tmp.getStaffId();
			tmp.setStaffId(hospitalUtil.idWrapper(staffId, (byte) 2));
		}
		return SUCCESS;
	}

	public String recordPage() {
		return SUCCESS;
	}

	public String checkPassword() {
		String encryptedPw = patientService.checkPassword();
		if (encryptedPw.equals(hospitalUtil.encrypt(password))) {
			passwordConfirm = true;
		} else {
			passwordConfirm = false;
		}
		return SUCCESS;
	}

	public String recordList() {
		recordDetailList = patientService.getRecordDetailList();
		Iterator<RecordDetailModel> it = recordDetailList.iterator();
		RecordDetailModel tmp = new RecordDetailModel();
		long patientId, doctorId;
		while (it.hasNext()) {
			tmp = it.next();
			patientId = tmp.getPatientId();
			tmp.setPatientId(hospitalUtil.idWrapper(patientId, (byte) 0));
			doctorId = tmp.getDoctorId();
			tmp.setDoctorId(hospitalUtil.idWrapper(doctorId, (byte) 1));
		}
		return SUCCESS;
	}

	public String passwordPage() {
		return SUCCESS;
	}

	public String changePassword() {
		String encryptedPw = patientService.checkPassword();
		if (encryptedPw.equals(hospitalUtil.encrypt(origPassword))) {
			if (newPassword.length() < 6) {
				flag = false;
				message = "Password needs to be at least 6 characters long";
				return SUCCESS;
			}
			if (newPassword.equals(confirmedNewPassword)) {
				boolean result = patientService.changePassword(newPassword);
				if (result) {
					flag = true;
					message = "Change password successfully.";
					return SUCCESS;
				} else {
					flag = false;
					message = "Fail to change password.";
					return SUCCESS;
				}
			} else {
				flag = false;
				message = "New passwords do not match.";
				return SUCCESS;
			}
		} else {
			flag = false;
			message = "Incorrect password.";
			return SUCCESS;
		}

	}

	public String goBackToPatientHome() {
		return SUCCESS;
	}

	public String getFirstname() {
		return firstname;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}

	public String getLastname() {
		return lastname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getSin() {
		return sin;
	}

	public void setSin(String sin) {
		this.sin = sin;
	}

	public String getOhip() {
		return ohip;
	}

	public void setOhip(String ohip) {
		this.ohip = ohip;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getPhoneNum() {
		return phoneNum;
	}

	public void setPhoneNum(String phoneNum) {
		this.phoneNum = phoneNum;
	}

	public String getCellphone() {
		return cellphone;
	}

	public void setCellphone(String cellphone) {
		this.cellphone = cellphone;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getPostalCode() {
		return postalCode;
	}

	public void setPostalCode(String postalCode) {
		this.postalCode = postalCode;
	}

	public String getDefaultDoctor() {
		return defaultDoctor;
	}

	public void setDefaultDoctor(String defaultDoctor) {
		this.defaultDoctor = defaultDoctor;
	}

	public String getYear() {
		return year;
	}

	public void setYear(String year) {
		this.year = year;
	}

	public String getMonth() {
		return month;
	}

	public void setMonth(String month) {
		this.month = month;
	}

	public String getDay() {
		return day;
	}

	public void setDay(String day) {
		this.day = day;
	}

	public String getCurrentHealth() {
		return currentHealth;
	}

	public void setCurrentHealth(String currentHealth) {
		this.currentHealth = currentHealth;
	}

	public PatientInfoModel getPatientInfo() {
		return patientInfo;
	}

	public void setPatientInfo(PatientInfoModel patientInfo) {
		this.patientInfo = patientInfo;
	}

	public PatientService getPatientService() {
		return patientService;
	}

	public void setPatientService(PatientService patientService) {
		this.patientService = patientService;
	}

	public List<DocScheduleModel> getPatientAppointments() {
		return patientAppointments;
	}

	public void setPatientAppointments(List<DocScheduleModel> patientAppointments) {
		this.patientAppointments = patientAppointments;
	}

	public boolean isPasswordConfirm() {
		return passwordConfirm;
	}

	public void setPasswordConfirm(boolean passwordConfirm) {
		this.passwordConfirm = passwordConfirm;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public List<RecordDetailModel> getRecordDetailList() {
		return recordDetailList;
	}

	public void setRecordDetailList(List<RecordDetailModel> recordDetailList) {
		this.recordDetailList = recordDetailList;
	}

	public String getNewPassword() {
		return newPassword;
	}

	public void setNewPassword(String newPassword) {
		this.newPassword = newPassword;
	}

	public String getConfirmedNewPassword() {
		return confirmedNewPassword;
	}

	public void setConfirmedNewPassword(String confirmedNewPassword) {
		this.confirmedNewPassword = confirmedNewPassword;
	}

	public String getOrigPassword() {
		return origPassword;
	}

	public void setOrigPassword(String origPassword) {
		this.origPassword = origPassword;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	public HospitalUtil getHospitalUtil() {
		return hospitalUtil;
	}

	public void setHospitalUtil(HospitalUtil hospitalUtil) {
		this.hospitalUtil = hospitalUtil;
	}

}
